home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.lang.c
- Path: news.sprintlink.net!eskimo!scs
- From: scs@eskimo.com (Steve Summit)
- Subject: Re: looping & sscanf
- X-Nntp-Posting-Host: eskimo.com
- Message-ID: <DLyz1B.DvK@eskimo.com>
- Sender: news@eskimo.com (News User Id)
- Organization: schmorganization
- References: <DLtqMw.8Ao@emr1.emr.ca>
- Date: Tue, 30 Jan 1996 01:05:34 GMT
-
- In article <DLtqMw.8Ao@emr1.emr.ca>, jagrant@emr1.emr.ca (John Grant) writes:
- > In FORTRAN, I can read a set of numbers from a character string with an
- > 'internal read'...
- > How can I do this easily in C?
- >...
- > Perhaps I should loop through the string using strtok(), converting each
- > substring using atof()?
-
- Something like that, yes.
-
- > I'm sure it's straightforward, but I just can't see it (or find it in the FAQ).
-
- There are some clues in there, which are expanded with an example
- or two in the book-length version:
-
- 12.16: How can I read data from data files with particular formats?
- How can I read ten floats without having to use a jawbreaker
- scanf format
- like "%f %f %f %f %f %f %f %f %f %f"?
- How can I read an arbitrary number of fields from a line into an
- array?
-
- A: In general, there are three main ways of parsing data lines:
-
- ...
-
- 2. Break the line into fields separated by whitespace (or
- some other delimiter), using strtok() or the equivalent
- (see question 13.6), then deal with each field
- individually, perhaps with routines like atoi() and
- atof(). (Once the line is broken up, the code for
- handling the fields is much like the traditional code in
- main() for handling the argv array; see question 20.3.)
- This method is particularly useful for reading an
- arbitrary (i.e. not known in advance) number of fields
- from a line into an array.
-
- Here is a simple example which copies a line of up to 10
- floating-point numbers (separated by whitespace) into an
- array:
-
- #define MAXARGS 10
-
- char *av[MAXARGS];
- int ac, i;
- double array[MAXARGS];
-
- ac = makeargv(line, av, MAXARGS);
- for(i = 0; i < ac; i++)
- array[i] = atof(av[i]);
-
- (See question 13.6 for the definition of makeargv().)
-
- ...
-
- 13.6: How can I split up a string into whitespace-separated fields?
- How can I duplicate the process by which main() is handed argc
- and argv?
-
- A: The only Standard routine available for this kind of
- "tokenizing" is strtok...
-
- As an alternative, here is a routine I use for building an argv
- all at once:
-
- #include <ctype.h>
-
- int makeargv(char *string, char *argv[], int argvsize)
- {
- char *p = string;
- int i;
- int argc = 0;
-
- for(i = 0; i < argvsize; i++) {
- /* skip leading whitespace */
- while(isspace(*p))
- p++;
-
- if(*p != '\0')
- argv[argc++] = p;
- else {
- argv[argc] = 0;
- break;
- }
-
- /* scan over arg */
- while(*p != '\0' && !isspace(*p))
- p++;
- /* terminate arg: */
- if(*p != '\0' && i < argvsize-1)
- *p++ = '\0';
- }
-
- return argc;
- }
-
- Calling makeargv() is straightforward:
-
- char *av[10];
- int i, ac = makeargv(string, av, 10);
- for(i = 0; i < ac; i++)
- printf("\"%s\"\n", av[i]);
-
- [A call to makeargv will] modify the input string,
- by inserting \0's to terminate each field. If you'll need the
- original string later, make a copy before breaking it up.
-
- Steve Summit
- scs@eskimo.com
-